﻿using AutoMapper.Execution;
using SmartWMS.Common.Extensions;
using SmartWMS.Common.ResponseOutput;
using SmartWMS.Domain.Base;
using SmartWMS.Domain.BasicsDatum;
using SmartWMS.Domain.WarehouseManage;
using SmartWMS.EntityFramework;
using SmartWMS.Server.BasicsDatumServer.CategoryService.Dto;
using SmartWMS.Server.Repository;
using SmartWMS.Server.WarehouseManage.RelocationServices.Dto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SmartWMS.Server.WarehouseManage.RelocationServices
{
    /// <summary>
    /// 移库
    /// </summary>
    public class RelocationService : IRelocationService
    {
        /// <summary>
        /// 产品表
        /// </summary>
        private readonly IRepository<Product> _product;
        /// <summary>
        /// 单位仓储
        /// </summary>
        public readonly IRepository<Unit> _unitRepository;
        /// <summary>
        /// 库位仓储
        /// </summary>
        public readonly IRepository<Location> _locationRepository;
        /// <summary>
        /// 入库明细仓储
        /// </summary>
        public readonly IRepository<InWarehouseDetail> _InWarehouseDetailRepository;
        /// <summary>
        /// 仓库仓储
        /// </summary>
        public readonly IRepository<Warehouse> _warehouseRepository;
        /// <summary>
        /// 移库明细仓储
        /// </summary>
        public readonly IRepository<RelocationDetail> _relocationDetailRepository;
        private readonly IRepository<Product> _productRepository;
        private readonly IRepository<Category> _categoryRepository;
        /// <summary>
        /// 移库仓储
        /// </summary>
        public readonly IRepository<Relocation> _relocationRepository;
        //上下文
        public readonly SmartWMSContext _smartWMSContext;
        public RelocationService(IRepository<Product> product, IRepository<Unit> unitRepository, IRepository<Location> locationRepository, IRepository<InWarehouseDetail> inWarehouseDetailRepository, IRepository<Warehouse> warehouseRepository, IRepository<RelocationDetail> relocationDetailRepository, IRepository<Relocation> relocationRepository, SmartWMSContext smartWMSContext, IRepository<Product> productRepository, IRepository<Category> categoryRepository)
        {
            _product = product;
            _unitRepository = unitRepository;
            _locationRepository = locationRepository;
            _InWarehouseDetailRepository = inWarehouseDetailRepository;
            _warehouseRepository = warehouseRepository;
            _relocationDetailRepository = relocationDetailRepository;
            _relocationRepository = relocationRepository;
            _smartWMSContext = smartWMSContext;
            _productRepository = productRepository;
            _categoryRepository = categoryRepository;
        }
        /// <summary>
        /// 移库列表(分页)
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<Response<List<RelocationDto>>> GetRelocationList(RelocationInput input)
        {
            var relocation = _relocationRepository.GetListQuery();
            var relocationDetail = _relocationDetailRepository.GetListQuery();
            var warehouse = _warehouseRepository.GetListQuery();
            var location = _locationRepository.GetListQuery();
            var product = _product.GetListQuery();
            var InWarehouseDetail = _InWarehouseDetailRepository.GetListQuery();
            var list = (from a in relocation
                        join b in relocationDetail on a.RelocationCode equals b.RelocationCode
                        join c in warehouse on b.WareHouseId equals c.Id
                        join d in warehouse on b.MoveNewWareHouseId equals d.Id
                        join e in location on b.OriginallocationId equals e.Id
                        join f in location on b.MoveLocationId equals f.Id
                        join g in product on b.ProductCode equals g.ProductCode
                        join t in InWarehouseDetail on g.ProductCode equals t.ProductCode
                        select new RelocationDto
                        {
                            Id = a.Id,
                            RelocationCode = a.RelocationCode,
                            RelocationType = a.RelocationType,
                            State = a.State,
                            Reviewer = a.Reviewer,
                            Opinion = a.Opinion,
                            Audittime = a.Audittime,
                            Creator = a.Creator,
                            CreatorTime = a.CreatorTime,
                            Remarks = a.Remarks,
                            ProductCode = g.ProductCode,
                            ProductName = g.ProductName,
                            Batch = t.Batch,
                            Number = b.Number,
                            UnitName = g.Unit,
                            OldWarehouseName = c.Name,
                            OldLocationName = e.LocationName,
                            NewWarehouseName = d.Name,
                            NewLocationName = f.LocationName,
                            OriginallocationId = e.Id,
                            MoveLocationId = f.Id,
                            WarehouseId = c.Id,
                            MoveNewWareHouseId = d.Id
                        }).AsEnumerable().DistinctBy(x => x.Id).ToList();
            if (!string.IsNullOrEmpty(input.RelocationCode))
            {
                list = list.Where(x => x.RelocationCode.Contains(input.RelocationCode)).ToList();
            }
            if (!string.IsNullOrEmpty(input.RelocationType))
            {
                list = list.Where(x => x.RelocationType.Contains(input.RelocationType)).ToList();
            }
            if (input.State != 0)
            {
                list = list.Where(x => x.State == input.State).ToList();
            }
            int totalCount = list.Count();
            int pageCount = (int)Math.Ceiling(totalCount / (double)input.PageSize);
            list = list.Skip((input.PageIndex - 1) * input.PageSize).Take(input.PageSize).ToList();
            var response = list.MapToList<RelocationDto>();
            return response != null ? Response<List<RelocationDto>>.Ok(response, totalCount, pageCount) : Response<List<RelocationDto>>.Fail("查询失败");
        }
        /// <summary>
        /// 添加移库信息（实现一对多的关系）
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<Response<bool>> AddRelocation(RelocationAdd input)
        {
            var procureShop = input.RelocationDetailDTO;
            var RelocationDetail = procureShop.Select(x => new RelocationDetail
            {
                RelocationCode = input.RelocationCode,
                ProductCode = x.ProductCode,
                Number = x.BuyNumber,
                WareHouseId = x.WarehouseId,
                OriginallocationId = x.OriginallocationId,
                MoveNewWareHouseId = x.MoveNewWareHouseId,
                MoveLocationId = x.MoveLocationId,
                Remarks = x.Remarks
            }).ToList();
            using (var tran = _smartWMSContext.Database.BeginTransaction())
            {
                try
                {
                    var i = await _relocationRepository.InsertAsync(input.MapTo<Relocation>());
                    if (i > 0)
                    {
                        var j = await _relocationDetailRepository.InsertAsync(RelocationDetail);
                        if (j > 0)
                        {
                            tran.Commit();
                            return Response<bool>.Ok(true);
                        }
                        else
                        {
                            tran.Rollback();
                            return Response<bool>.Fail("添加失败");
                        }
                    }
                    else
                    {
                        tran.Rollback();
                        return Response<bool>.Fail("添加失败");
                    }
                }
                catch (Exception)
                {

                    throw;
                }
            }
        }
        /// <summary>
        /// 查看移库
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<RelocationDto> GetRelocationview(ShowId Id)
        {
            var relocation = await _relocationRepository.GetAllListAsync();
            var relocationD = await _relocationDetailRepository.GetAllListAsync();
            var list = (from a in relocation
                        join b in relocationD on a.RelocationCode equals b.RelocationCode
                        where a.Id == Id.Id
                        select new RelocationDto
                        {
                            Id = a.Id,
                            RelocationCode = a.RelocationCode,
                            RelocationType = a.RelocationType,
                            State = a.State,
                            Reviewer = a.Reviewer,
                            Opinion = a.Opinion,
                            Audittime = a.Audittime,
                            Creator = a.Creator,
                            CreatorTime = a.CreatorTime,
                            Remarks = a.Remarks,

                        }).FirstDynamic();
            return list;
        }
        /// <summary>
        /// 查看移库列表
        /// </summary>
        /// <param name="Id"></param>
        /// <returns></returns>
        public async Task<Response<List<RelocationDto>>> GetRelocation(ShowId Id)
        {
            var relocation = await _relocationRepository.GetAllListAsync();
            var relocationDetail = await _relocationDetailRepository.GetAllListAsync();
            var product = await _product.GetAllListAsync();
            var location = await _locationRepository.GetAllListAsync();
            var warehouse = await _warehouseRepository.GetAllListAsync();
            var unit = await _unitRepository.GetAllListAsync();
            var InWarehouseDetail = await _InWarehouseDetailRepository.GetAllListAsync();
            var list = (from a in relocation
                        join b in relocationDetail on a.RelocationCode equals b.RelocationCode
                        join c in warehouse on b.WareHouseId equals c.Id
                        join d in warehouse on b.MoveNewWareHouseId equals d.Id
                        join e in location on b.OriginallocationId equals e.Id
                        join f in location on b.MoveLocationId equals f.Id
                        join g in product on b.ProductCode equals g.ProductCode
                        join t in InWarehouseDetail on g.ProductCode equals t.ProductCode
                        where a.Id == Id.Id
                        select new RelocationDto
                        {
                            Id = a.Id,
                            ProductCode = b.ProductCode,
                            ProductName = g.ProductName,
                            UnitName = g.Unit,
                            Batch = t.Batch,
                            Number = b.Number,
                            OriginallocationId = e.Id,
                            MoveLocationId = f.Id,
                            WarehouseId = c.Id,
                            MoveNewWareHouseId = d.Id,
                            OldLocationName = c.Name + e.LocationName,
                            NewLocationName = d.Name + f.LocationName,
                        }).DistinctBy(s => s.Id).ToList();
            var plist = list.MapToList<RelocationDto>();
            return plist != null ? Response<List<RelocationDto>>.Ok(plist) : Response<List<RelocationDto>>.Fail("查询失败");
        }
        /// <summary>
        /// 批量删除移库管理
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Response<bool>> DeleteRelocationList(List<RelocationDto> dto)
        {
            var list = _relocationRepository.GetListQuery().Where(x => dto.Select(x => x.RelocationCode).Contains(x.RelocationCode)).ToList();
            var plist = _relocationDetailRepository.GetListQuery().Where(x => list.Select(x => x.RelocationCode).Contains(x.RelocationCode)).ToList();
            if (list != null)
            {
                using (var tran = _smartWMSContext.Database.BeginTransaction())
                {
                    try
                    {
                        var result = await _relocationRepository.DeleteAsync(list);
                        if (result > 0)
                        {
                            if (plist != null)
                            {
                                var i = await _relocationDetailRepository.DeleteAsync(plist);
                                if (i > 0)
                                {
                                    tran.Commit();
                                    return Response<bool>.Ok(true);
                                }
                                else
                                {
                                    tran.Rollback();
                                    return Response<bool>.Fail(false);
                                }
                            }
                            else
                            {
                                tran.Rollback();
                                return Response<bool>.Fail(false);
                            }
                        }
                        else
                        {
                            tran.Rollback();
                            return Response<bool>.Fail(false);
                        }
                    }
                    catch (Exception)
                    {

                        throw;
                    }
                }
            }
            else
            {
                return Response<bool>.Fail(false);
            }
        }
        /// <summary>
        /// 删除移库信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<Response<bool>> DeleteRelocation(RelocationDto input)
        {
            var list = _relocationRepository.GetListQuery().FirstOrDefault(x => x.RelocationCode == input.RelocationCode);
            var plist = await _relocationDetailRepository.GetAllListAsync();
            plist = plist.Where(x => x.RelocationCode == input.RelocationCode).ToList();
            if (list != null)
            {
                using (var tran = _smartWMSContext.Database.BeginTransaction())
                {
                    try
                    {
                        var result = await _relocationRepository.DeleteByIdAsync(list);
                        if (result > 0)
                        {
                            if (plist != null)
                            {
                                var i = await _relocationDetailRepository.DeleteAsync(plist);
                                if (i > 0)
                                {
                                    tran.Commit();
                                    return Response<bool>.Ok(true);
                                }
                                else
                                {
                                    tran.Rollback();
                                    return Response<bool>.Fail(false);
                                }
                            }
                            else
                            {
                                tran.Rollback();
                                return Response<bool>.Fail(false);
                            }
                        }
                        else
                        {
                            tran.Rollback();
                            return Response<bool>.Fail(false);
                        }
                    }
                    catch (Exception)
                    {

                        throw;
                    }
                }
            }
            else
            {
                return Response<bool>.Fail(false);
            }

        }
        /// <summary>
        /// 移库信息审核通过
        /// </summary>
        /// <param name="category"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Response<bool>> UpdAteaudit(RelocationDto dto)
        {
            var relocation1 = dto.MapTo<Relocation>();
            var result = _relocationRepository.UpdateAsync(relocation1);
            return result.Result > 0 ? Response<bool>.Ok(result.Result > 0) :
                  Response<bool>.Fail(result.Result > 0);
        }
        /// <summary>
        /// 移库信息审核不通过
        /// </summary>
        /// <param name="category"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Response<bool>> UpdAteaudit1(RelocationDto dto)
        {
            var relocation1 = dto.MapTo<Relocation>();
            var result = _relocationRepository.UpdateAsync(relocation1);
            return result.Result > 0 ? Response<bool>.Ok(result.Result > 0) :
                  Response<bool>.Fail(result.Result > 0);
        }
        /// <summary>
        /// 反填
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public RelocationAdd SelRelocation(RelocationAdd dto)
        {
            var relocation = _relocationRepository.GetListQuery();
            var relocationDetail = _relocationDetailRepository.GetListQuery();
            var product = _product.GetListQuery();
            var location = _locationRepository.GetListQuery();
            var warehouse = _warehouseRepository.GetListQuery();
            var unit = _unitRepository.GetListQuery();
            var InWarehouseDetail = _InWarehouseDetailRepository.GetListQuery();
            var list = (from a in relocation
                        join b in relocationDetail on a.RelocationCode equals b.RelocationCode
                        join c in warehouse on b.WareHouseId equals c.Id
                        join d in warehouse on b.MoveNewWareHouseId equals d.Id
                        join e in location on b.OriginallocationId equals e.Id
                        join f in location on b.MoveLocationId equals f.Id
                        join g in product on b.ProductCode equals g.ProductCode
                        join t in InWarehouseDetail on g.ProductCode equals t.ProductCode
                        where a.RelocationCode == dto.RelocationCode
                        select new RelocationDetailDTO
                        {
                            Id = b.Id,
                            ProductCode = b.ProductCode,
                            ProductName = g.ProductName,
                            UnitName = g.Unit,
                            Batch = t.Batch,
                            BuyNumber = b.Number,
                            OriginallocationId = e.Id,
                            MoveLocationId = f.Id,
                            WarehouseId = c.Id,
                            Specs = g.Specs,
                            Price = g.Price,
                            MoveNewWareHouseId = d.Id,
                            OldLocationName = e.LocationName,
                            NewLocationName = f.LocationName,
                            OldWarehouseName = c.Name,
                            NewWarehouseName = d.Name,
                        }).AsEnumerable().DistinctBy(x => x.Id).ToList();
            var list1 = _relocationRepository.GetListQuery().FirstOrDefault(x => x.RelocationCode == dto.RelocationCode);
            var slist = list1.MapTo<RelocationAdd>();
            slist.RelocationDetailDTO = list.MapToList<RelocationDetailDTO>();
            return slist;
        }
        /// <summary>
        /// 修改移库信息（实现一对多的关系）
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<Response<bool>> EditRelocation(RelocationAdd input)
        {
            var procureShop = input.RelocationDetailDTO;
            var RelocationDetail = procureShop.Select(x => new RelocationDetail
            {
                Id = x.Id,
                RelocationCode = input.RelocationCode,
                ProductCode = x.ProductCode,
                Number = x.BuyNumber,
                WareHouseId = x.WarehouseId,
                OriginallocationId = x.OriginallocationId,
                MoveNewWareHouseId = x.MoveNewWareHouseId,
                MoveLocationId = x.MoveLocationId,
                Remarks = x.Remarks
            }).Distinct().ToList();
            using (var tran = _smartWMSContext.Database.BeginTransaction())
            {
                try
                {
                    var i = await _relocationRepository.UpdateAsync(input.MapTo<Relocation>());
                    if (i > 0)
                    {
                        var j = await _relocationDetailRepository.UpdateRangeAsync(RelocationDetail);
                        if (j > 0)
                        {
                            tran.Commit();
                            return Response<bool>.Ok(true);
                        }
                        else
                        {
                            tran.Rollback();
                            return Response<bool>.Fail("修改失败");
                        }
                    }
                    else
                    {
                        tran.Rollback();
                        return Response<bool>.Fail("修改失败");
                    }
                }
                catch (Exception)
                {

                    throw;
                }
            }
        }

        /// <summary>
        /// 显示查询选中产品数据
        /// </summary>
        /// <returns></returns>
        public async Task<Response<List<ProductListDto>>> GetProductList(ProductLisInput input)
        {
            var list = await _productRepository.GetAllListAsync();
            var unit = await _unitRepository.GetAllListAsync();
            var category = await _categoryRepository.GetAllListAsync();
            var location = await _locationRepository.GetAllListAsync();
            var warehouse = await _warehouseRepository.GetAllListAsync();
            var response = (from a in list
                            join c in category on a.ProductTypeId equals c.Id
                            join d in location on a.DefaultLocationId equals d.Id
                            join e in warehouse on a.DefaultWarehouseId equals e.Id
                            select new ProductListDto
                            {
                                Id = a.Id,
                                ProductId = a.Id,
                                ProductCode = a.ProductCode,
                                ProductName = a.ProductName,
                                Specs = a.Specs,
                                UnitName = a.Unit,
                                Price = a.Price,
                                CategoryName = c.CategoryName,
                                PackageType = a.PackageType,
                                Weight = a.Weight,
                                OldLocationName = d.LocationName,
                                OriginallocationId = d.Id,
                                OldWarehouseName = e.Name,
                                WarehouseId = e.Id,
                                MoveLocationId = d.Id,
                                MoveNewWareHouseId = e.Id,
                                //Number = 0,
                                //TotalPrice = 0,
                            }).ToList();
            if (!string.IsNullOrEmpty(input.ProductCode))
            {
                response = response.Where(x => x.ProductCode.Contains(input.ProductCode)).ToList();
            }
            if (!string.IsNullOrEmpty(input.ProductName))
            {
                response = response.Where(x => x.ProductName.Contains(input.ProductName)).ToList();
            }
            int totalCount = response.Count();
            int pageCount = (int)Math.Ceiling(totalCount / (double)input.pageSize);
            response = response.Skip((input.pageIndex - 1) * input.pageSize).Take(input.pageSize).ToList();
            var plist = response.MapToList<ProductListDto>();
            return plist != null ? Response<List<ProductListDto>>.Ok(plist, totalCount, pageCount) : Response<List<ProductListDto>>.Fail("查询失败");
        }
    }
}
